package com.dk.activiti;


import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootActivitiDemo {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;
    /**
     * 启动流程实例
     */
    @Test
    public void testStartProcess(){
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey("myLeave");
// 输出内容
        System.out.println("流程定义id：" +
                processInstance.getProcessDefinitionId());
        System.out.println("流程实例id：" + processInstance.getId());
        System.out.println("当前活动Id：" +
                processInstance.getActivityId());
    }

    /**
     * 查询当前个人待执行的任务
     */
    @Test
    public void testFindPersonalTaskList() {
// 任务负责人
        String assignee = "worker";
// 根据流程key 和 任务负责人 查询任务
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("myLeave") //流程Key
                .taskAssignee(assignee)//只查询该任务负责人的任务
                .list();
        for (Task task : list) {
            System.out.println("流程实例id：" +
                    task.getProcessInstanceId());
            System.out.println("任务id：" + task.getId());
            System.out.println("任务负责人：" + task.getAssignee());
            System.out.println("任务名称：" + task.getName());
        }
    }

    /**
     * 流程任务处理
     * 任务负责人查询到代办任务后，可以选择任务进行处理，完成任务。
     */
    // 完成任务
    @Test
    public void completTask(){
// 根据流程key 和 任务的负责人 查询任务
// 返回一个任务对象
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myLeave") //流程Key
                .taskAssignee("worker") //要查询的负责人
                .singleResult();
// 完成任务,参数：任务id
        taskService.complete(task.getId());
    }
    /**
     * 查询流程定义
     * 这一步可以查询流程相关信息，包含流程定义，流程部署，流程版本
     */
    @Test
    public void queryProcessDefinition(){
// 得到ProcessDefinitionQuery 对象
        ProcessDefinitionQuery processDefinitionQuery =
                repositoryService.createProcessDefinitionQuery();
// 查询出当前所有的流程定义
// 条件：processDefinitionKey =evection
// orderByProcessDefinitionVersion 按照版本排序
// desc倒叙
// list 返回集合
        List<ProcessDefinition> definitionList =
                processDefinitionQuery.processDefinitionKey("myLeave")
                        .orderByProcessDefinitionVersion()
                        .desc()
                        .list();
// 输出流程定义信息
        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义 id="+processDefinition.getId());
            System.out.println("流程定义 name="+processDefinition.getName());
                    System.out.println("流程定义 key="+processDefinition.getKey());
            System.out.println("流程定义 Version="+processDefinition.getVersion());
                    System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
        }
    }
    /**
     * 查询流程实例
     */
    @Test
    public void queryProcessInstance() {
// 流程定义key
        String processDefinitionKey = "myLeave";
        List<ProcessInstance> list = runtimeService
                .createProcessInstanceQuery()
                .processDefinitionKey(processDefinitionKey)//
                .list();
        for (ProcessInstance processInstance : list) {
            System.out.println("----------------------------");
            System.out.println("流程实例id："
                    + processInstance.getProcessInstanceId());
            System.out.println("所属流程定义id："
                    + processInstance.getProcessDefinitionId());
            System.out.println("是否执行完成：" +
                    processInstance.isEnded());
            System.out.println("是否暂停：" +
                    processInstance.isSuspended());
            System.out.println("当前活动标识：" +
                    processInstance.getActivityId());
            System.out.println("业务关键字："+processInstance.getBusinessKey());
        }
    }

    /**
     * 删除流程
     * 这里只删除了流程定义，不会删除历史表信息
     */
    @Test
    public void deleteDeployment() {
// 流程部署id
        String deploymentId = "1";
//删除流程定义，如果该流程定义已有流程实例启动则删除时出错
        repositoryService.deleteDeployment(deploymentId);
//设置true 级联删除流程定义，即使该流程有流程实例启动也可以删除，设置为false非级别删除方式，如果流程
// repositoryService.deleteDeployment(deploymentId, true);
    }
    @Test
    public void queryBpmnFile() throws IOException {
// 3、得到查询器：ProcessDefinitionQuery，设置查询条件,得到想要的流程定义
        ProcessDefinition processDefinition =
                repositoryService.createProcessDefinitionQuery()
                        .processDefinitionKey("myLeave")
                        .singleResult();
// 4、通过流程定义信息，得到部署ID
        String deploymentId = processDefinition.getDeploymentId();
// 5、通过repositoryService的方法，实现读取图片信息和bpmn信息
// png图片的流
        InputStream pngInput =
                repositoryService.getResourceAsStream(deploymentId,
                        processDefinition.getDiagramResourceName());
// bpmn文件的流
        InputStream bpmnInput =
                repositoryService.getResourceAsStream(deploymentId,
                        processDefinition.getResourceName());
// 6、构造OutputStream流
        File file_png = new File("d:/myLeave.png");
        File file_bpmn = new File("d:/myLeave.bpmn");
        FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
        FileOutputStream pngOut = new FileOutputStream(file_png);
// 7、输入流，输出流的转换
        IOUtils.copy(pngInput,pngOut);
        IOUtils.copy(bpmnInput,bpmnOut);
// 8、关闭流
        pngOut.close();
        bpmnOut.close();
        pngInput.close();
        bpmnInput.close();
    }
    /**
     * 查看历史信息
     */
    @Test
    public void findHistoryInfo(){
// 获取 actinst表的查询对象
        HistoricActivityInstanceQuery instanceQuery =
                historyService.createHistoricActivityInstanceQuery();
// 查询 actinst表，条件：根据 InstanceId 查询，查询一个流程的所有历史信息
        instanceQuery.processInstanceId("25001");
// 查询 actinst表，条件：根据 DefinitionId 查询，查询一种流程的所有历史信息
// instanceQuery.processDefinitionId("myLeave:1:22504");
// 增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
// 查询所有内容
        List<HistoricActivityInstance> activityInstanceList =
                instanceQuery.list();
// 输出
        for (HistoricActivityInstance hi : activityInstanceList) {
            System.out.println(hi.getActivityId());
            System.out.println(hi.getActivityName());
            System.out.println(hi.getProcessDefinitionId());
            System.out.println(hi.getProcessInstanceId());
            System.out.println("<==========================>");
        }
    }
}